﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SlimDX;
using Gype.UI;

namespace Gype.GUI.Components
{
    public class MenuBarPopup
    {
        internal void DrawItem(Vector2 position)
        {
            if (string.IsNullOrEmpty(Text) || mTarget == null)
                return;

            if (IsHovered)
            {
                RectangleFillMask mask = RectangleFillMask.All;
                if (IsExpanded)
                    mask &= ~RectangleFillMask.Bottom;

                mTarget.FillRectangle(position + new Vector2(1, 1), new Vector2(mTextSize.X + 1, 19 + (IsExpanded ? 1 : 0)), BrushCollection.MenuBarItemBackground);
                mTarget.DrawRectangle(position, new Vector2(mTextSize.X + 2, 20), BrushCollection.MenuBarItemBorder, 1, mask);
            }

            mItemText.DrawText(Text, position + new Vector2(0, 1.5f), mTextSize);

            if (IsExpanded && mPopupItems.Count > 0)
            {
                mTarget.FillRectangle(position + new Vector2(1, 21), new Vector2(mPopupSize.X - 2, mPopupSize.Y + 8), BrushCollection.MenuBarItemBackground);
                mTarget.DrawRectangle(position + new Vector2(0, 20), new Vector2(mPopupSize.X, mPopupSize.Y + 10), BrushCollection.MenuBarItemBorder, 1,
                    RectangleFillMask.Bottom | RectangleFillMask.Right | RectangleFillMask.Left);

                mTarget.DrawRectangle(position + new Vector2(mTextSize.X + 1, 20), new Vector2(mPopupSize.X - mTextSize.X - 1, 2), BrushCollection.MenuBarItemBorder, 1,
                    RectangleFillMask.Top);

                Vector2 startPos = position + new Vector2(5, 25);
                foreach (var item in mPopupItems)
                {
                    item.RenderObject(startPos, new Vector2(mPopupSize.X - 10, 19));
                    startPos.Y += 19;
                }
            }
        }

        internal void AttachedToBar(MenuBar bar)
        {
            mTarget = bar.mGUIManager.Target;
            mItemText = new TextElement(TextCollection.Arial);
            mPopupText = new TextElement(TextCollection.Arial);
            mPopupText.Alignment = TextAlignement.Left;

            if (!string.IsNullOrEmpty(Text))
            {
                var size = mItemText.MeasureString(mText);
                mTextSize = new Vector2(size.Width, size.Height);
                if (mTextSize.Y > 16)
                    mTextSize.Y = 16;
            }

            AddPopupItem(new MenuBarPopupItem("Open"));
            AddPopupItem(new MenuBarPopupItem("Close"));
            AddPopupItem(new MenuBarPopupItem("Add new friend"));
        }

        public string Text
        {
            get { return mText; }
            set
            {
                mText = value;
                if (mItemText == null)
                    return;

                var size = mItemText.MeasureString(mText);
                mTextSize = new Vector2(size.Width, size.Height);
                if (mTextSize.Y > 16)
                    mTextSize.Y = 16;
            }
        }

        internal void HandleMessage(Vector2 position, ControlMessage message)
        {
            if (!IsExpanded || (message is MouseMessage) == false)
                return;

            Vector2 popupStart = new Vector2(position.X, position.Y + 23);
            Vector2 popupEnd = popupStart + mPopupSize;
            popupEnd.Y += 10;
            MouseMessage msg = message as MouseMessage;
            Vector2 mousePos = new Vector2(msg.X, msg.Y);

            if (msg.X >= popupStart.X && msg.Y >= popupStart.Y && msg.X <= popupEnd.X && msg.Y <= popupEnd.Y)
            {
                Vector2 popupRelPos = new Vector2(msg.X, msg.Y) - popupStart;
                switch (message.Message)
                {
                    case Win32Native.WM.LBUTTONDOWN:
                        {
                            MenuBarPopupItem pressItem = ItemFromPoint(popupRelPos.X, popupRelPos.Y);
                            mItemDown = pressItem;
                        }
                        break;

                    case Win32Native.WM.LBUTTONUP:
                        {
                            MenuBarPopupItem releaseItem = ItemFromPoint(popupRelPos.X, popupRelPos.Y);
                            if (releaseItem != null && releaseItem == mItemDown)
                            {
                                Console.WriteLine("Clicked an item: " + mItemDown.Text);
                            }

                            mItemDown = null;
                        }
                        break;

                    case Win32Native.WM.MOUSEMOVE:
                        {
                            MenuBarPopupItem hover = ItemFromPoint(popupRelPos.X, popupRelPos.Y);
                            if (hover != mItemHover && mItemHover != null)
                            {
                                mItemHover.IsHovered = false;
                            }

                            if (hover != null)
                            {
                                hover.IsHovered = true;
                            }

                            mItemHover = hover;
                        }
                        break;
                }
            }
            else
            {
                if (message.Message == Win32Native.WM.MOUSEMOVE)
                {
                    if (mItemHover != null)
                    {
                        mItemHover.IsHovered = false;
                        mItemHover = null;
                    }
                }
                if (message.Message == Win32Native.WM.LBUTTONUP)
                {
                    if (mItemDown != null)
                        mItemDown = null;
                }
            }
        }

        internal MenuBarPopupItem ItemFromPoint(float x, float y)
        {
            if (y < 5)
                return null;

            y -= 5;
            int index = (int)(y / 19);
            if (index >= mPopupItems.Count || index < 0)
                return null;

            return mPopupItems[index];
        }

        public void AddPopupItem(MenuBarPopupItem item)
        {
            System.Drawing.SizeF stringSize = mItemText.MeasureString(item.Text, new Vector2(500, 16));
            if (stringSize.Width + 16 > mPopupSize.X)
                mPopupSize.X = stringSize.Width + 16;

            mPopupSize.Y += stringSize.Height + 2;
            item.AttachedToPopup(this);
            mPopupItems.Add(item);
        }

        public void Expand() { IsExpanded = true; }
        public void Collapse() { IsExpanded = false; }

        public Vector2 TextSize { get { return mTextSize; } }

        internal bool IsHovered = false;
        internal bool IsExpanded = false;
        internal Vector2 mPopupSize = new Vector2(100, 0);
        
        private List<MenuBarPopupItem> mPopupItems = new List<MenuBarPopupItem>();
        private string mText;
        private TextElement mItemText;
        private TextElement mPopupText;
        private Rendertarget mTarget;
        private Vector2 mTextSize;
        private MenuBarPopupItem mItemDown = null;
        private MenuBarPopupItem mItemHover = null;
    }
}
